Why
為什麼要用到資料庫呢?
因為如果我們把攻略資料都寫死,寫成文字檔案,
像是大篇幅文章一樣的話
那要新增、修改文章的人是不是都要懂 HTML 跟 PHP 語法
如果可以有一個地方可以儲存資料,我們透過管理後台修改資料後
大家瀏覽的網站資料就會自動更新,全程不用碰到程式碼。
那程式設計師就可以去做更有趣的開發工作了。
How
我們需要安裝一個資料庫,用途是來儲存資料。
市面上有非常多種資料庫可以使用
今天要講的是 MYSQL 也是最常跟 PHP 配合的夥伴
安裝方式可以上網 Google 依據你的作業系統,
資料已經多到爆掉,我這邊就不提了。
我要用昨天的 class 把連接的方式物件化,
實作出簡單好用的物件,來應用到後續的實作上!
What
直接來看 class 類別設計書:
<?php
class DatabaseAccessObject {
private $mysql_address = "";
private $mysql_username = "";
private $mysql_password = "";
private $mysql_database = "";
private $link;
private $last_sql = "";
private $last_id = 0;
private $last_num_rows = 0;
private $error_message = "";
/**
* 這段是『建構式』會在物件被 new 時自動執行,裡面主要是建立跟資料庫的連接,並設定語系是萬國語言以支援中文
*/
public function __construct($mysql_address, $mysql_username, $mysql_password, $mysql_database) {
$this->mysql_address = $mysql_address;
$this->mysql_username = $mysql_username;
$this->mysql_password = $mysql_password;
$this->mysql_database = $mysql_database;
$this->link = ($GLOBALS["___mysqli_ston"] = mysqli_connect($this->mysql_address, $this->mysql_username, $this->mysql_password));
if (mysqli_connect_errno())
{
$this->error_message = "Failed to connect to MySQL: " . mysqli_connect_error();
echo $this->error_message;
return false;
}
mysqli_query($GLOBALS["___mysqli_ston"], "SET NAMES utf8");
mysqli_query($this->link, "SET NAMES utf8");
mysqli_query($this->link, "SET CHARACTER_SET_database= utf8");
mysqli_query($this->link, "SET CHARACTER_SET_CLIENT= utf8");
mysqli_query($this->link, "SET CHARACTER_SET_RESULTS= utf8");
if(!(bool)mysqli_query($this->link, "USE ".$this->mysql_database))$this->error_message = 'Database '.$this->mysql_database.' does not exist!';
}
/**
* 這段是『解構式』會在物件被 unset 時自動執行,裡面那行指令是切斷跟資料庫的連接
*/
public function __destruct() {
mysqli_close($this->link);
}
/**
* 這段用來執行 MYSQL 資料庫的語法,可以靈活使用
*/
public function execute($sql = null) {
if ($sql===null) return false;
$this->last_sql = str_ireplace("DROP","",$sql);
$result_set = array();
$result = mysqli_query($this->link, $this->last_sql);
if (((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false))) {
$this->error_message = "MySQL ERROR: " . ((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false));
} else {
$this->last_num_rows = @mysqli_num_rows($result);
for ($xx = 0; $xx < @mysqli_num_rows($result); $xx++) {
$result_set[$xx] = mysqli_fetch_assoc($result);
}
if(isset($result_set)) {
return $result_set;
}else{
$this->error_message = "result: zero";
}
}
}
/**
* 這段用來讀取資料庫中的資料,回傳的是陣列資料
*/
public function query($table = null, $condition = "1", $order_by = "1", $fields = "*", $limit = ""){
$sql = "SELECT {$fields} FROM {$table} WHERE {$condition} ORDER BY {$order_by} {$limit}";
return $this->execute($sql);
}
/**
* 這段可以新增資料庫中的資料,並把最後一筆的 ID 存到變數中,可以用 getLastId() 取出
*/
public function insert($table = null, $data_array = array()) {
if($table===null)return false;
if(count($data_array) == 0) return false;
$tmp_col = array();
$tmp_dat = array();
foreach ($data_array as $key => $value) {
$value = mysqli_real_escape_string($this->link, $value);
$tmp_col[] = $key;
$tmp_dat[] = "'$value'";
}
$columns = join(",", $tmp_col);
$data = join(",", $tmp_dat);
$this->last_sql = "INSERT INTO " . $table . "(" . $columns . ")VALUES(" . $data . ")";
mysqli_query($this->link, $this->last_sql);
if (((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false))) {
echo "MySQL Update Error: " . ((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false));
} else {
$this->last_id = mysqli_insert_id($this->link);
return $this->last_id;
}
}
/**
* 這段可以更新資料庫中的資料
*/
public function update($table = null, $data_array = null, $key_column = null, $id = null) {
if($table == null){
echo "table is null";
return false;
}
if($id == null) return false;
if($key_column == null) return false;
if(count($data_array) == 0) return false;
$id = mysqli_real_escape_string($this->link, $id);
$setting_list = "";
for ($xx = 0; $xx < count($data_array); $xx++) {
list($key, $value) = each($data_array);
$value = mysqli_real_escape_string($this->link, $value);
$setting_list .= $key . "=" . "\"" . $value . "\"";
if ($xx != count($data_array) - 1)
$setting_list .= ",";
}
$this->last_sql = "UPDATE " . $table . " SET " . $setting_list . " WHERE " . $key_column . " = " . "\"" . $id . "\"";
$result = mysqli_query($this->link, $this->last_sql);
if (((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false))) {
echo "MySQL Update Error: " . ((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false));
} else {
return $result;
}
}
/**
* 這段可以刪除資料庫中的資料
*/
public function delete($table = null, $key_column = null, $id = null) {
if ($table===null) return false;
if($id===null) return false;
if($key_column===null) return false;
return $this->execute("DELETE FROM $table WHERE " . $key_column . " = " . "\"" . $id . "\"");
}
/**
* @return string
* 這段會把最後執行的語法回傳給你
*/
public function getLastSql() {
return $this->last_sql;
}
/**
* @param string $last_sql
* 這段是把執行的語法存到變數裡,設定成 private 只有內部可以使用,外部無法呼叫
*/
private function setLastSql($last_sql) {
$this->last_sql = $last_sql;
}
/**
* @return int
* 主要功能是把新增的 ID 傳到物件外面
*/
public function getLastId() {
return $this->last_id;
}
/**
* @param int $last_id
* 把這個 $last_id 存到物件內的變數
*/
private function setLastId($last_id) {
$this->last_id = $last_id;
}
/**
* @return int
*/
public function getLastNumRows() {
return $this->last_num_rows;
}
/**
* @param int $last_num_rows
*/
private function setLastNumRows($last_num_rows) {
$this->last_num_rows = $last_num_rows;
}
/**
* @return string
* 取出物件內的錯誤訊息
*/
public function getErrorMessage()
{
return $this->error_message;
}
/**
* @param string $error_message
* 記下錯誤訊息到物件變數內
*/
private function setErrorMessage($error_message)
{
$this->error_message = $error_message;
}
}
我們可以這樣使用這個物件 Object
$mysql_address = "localhost"; // 通常是連接同一台機器,如果是遠端就設 IP
$mysql_username = "root"; // 設定連接資料庫用戶帳號
$mysql_password = "password"; // 設定連接資料庫用戶的密碼
$mysql_database = "game"; // 設成你在 mysql 創的資料庫
$DAO = new DatabaseAccessObject($mysql_address, $mysql_username, $mysql_password, $mysql_database);
// 要新增資料就:
$table = "hero"; // 設定你想新增資料的資料表
$data_array['hero_name'] = "凡恩";
$data_array['hero_hp'] = 100;
$data_array['hero_mp'] = 80;
$DAO->insert($table, $data_array);
$hero_id = $DAO->getLastId; // 可以拿到他自動建立的 id
// 這樣就完成新增動作了
// 想要查詢的話
$table = "hero"; // 設定你想查詢資料的資料表
$condition = "hero_name = '凡恩'";
$hero = $DAO->query($table, $condition, $order_by = "1", $fields = "*", $limit = "");
// 這樣寫等同於下面直接呼叫的語法:
$hero = $DAO->execute("SELECT * FROM hero WHERE hero_name = '凡恩'");
print_r($hero); // 可以印出來看看
// 那想修改資料呢?
$table = "hero";
$data_array['hero_name'] = "凡恩ATM"; // 想改他的名字
$key_column = "hero_id"; //
$id = $hero_id; // 根據我們剛剛上面拿到的 hero ID
$DAO->update($table, $data_array, $key_column, $id);
echo $DAO->getLastSql; // 想知道會轉換成什麼語法 可以印出來看看
// 最後的刪除也不難,告訴他條件就可以了
$table = "hero";
$key_column = "hero_id";
$id = 1; // 我們假設要刪除 hero_id = 1 的英雄
DAO->delete($table, $key_column, $id);
// 一行搞定
補上 hero 這張表的 SQL 語法 貼到 phpmyadmin 裡面先選好 database 後就可以新增囉
--
-- Table structure for table `hero`
--
CREATE TABLE IF NOT EXISTS `hero` (
`hero_id` int(11) NOT NULL,
`hero_name` varchar(30) NOT NULL,
`hero_hp` int(11) NOT NULL,
`hero_mp` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `hero`
--
ALTER TABLE `hero`
ADD PRIMARY KEY (`hero_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `hero`
--
ALTER TABLE `hero`
MODIFY `hero_id` int(11) NOT NULL AUTO_INCREMENT;
今天提供一個連接資料庫的 PHP 物件,有沒有感覺在使用上精簡很多
這是『封裝』的好處,另外我省略了一些資料庫的概念說明
這需要一些前置的課程,但是我覺得還是專注在 PHP 語法上做說明
如果有需要可以留言告訴我,我找地方另外開個主題來說明。
喜歡我的文章可以按個讚,也歡迎訂閱下一期教學文章,分享給想學程式的好朋友
請問一下這篇是不是沒有創建"hero"資料表的語法
沒問題!補上了
請問如果我有需要,想要知道更多,敢請可以留言告訴您嗎?謝謝!可以勞煩您找地方另外開個主題來說明嗎?感恩!
請問如果我有需要,想要知道更多,敢請可以留言告訴您嗎?謝謝!可以勞煩您找地方另外開個主題來說明嗎?感恩!
可以直接私我訊息哦
$hero_id = $DAO->getLastId;
出現Undefined property
請問是否應為$hero_id = $DAO->getLastId();
到這邊就有點跳太多ㄌ...完全跟不上R
要稍微補充一下SQL的基本知識
筆者沒有提到環境架設的部分,如果自己去建一次環境的話,再來看多少會比較好看懂
看到SQL 就.....銜接不上了
版大 有沒有看了甚麼東西 能比較理解中間那長串看起來不像php的東西可以參考呢
謝謝 !
$hero_id = $DAO->getLastId; // 可以拿到他自動建立的 id
echo $DAO->getLastSql; // 想知道會轉換成什麼語法 可以印出來看看
這兩行後面有少小括號,加上去後就不會有報錯了
$hero_id = $DAO->getLastId(); // 可以拿到他自動建立的 id
echo $DAO->getLastSql(); // 想知道會轉換成什麼語法 可以印出來看看
它存在一個問題??
資料庫帳號/密碼錯誤時??(這個當然屬於用戶設定上的問題??但還是要避免)
他會跳出這樣的錯誤訊息!!
直接在 mysqli_connect 這行就出錯了!!!
Fatal error: Uncaught mysqli_sql_exception: Access denied for user 'root'@'localhost' (using password: YES) in D:\laragon\www\sandbox-mcart\DatabaseAccessObject.php:22 Stack trace: #0 D:\laragon\www\sandbox-mcart\DatabaseAccessObject.php(22): mysqli_connect('localhost', 'root', 'password') #1 D:\laragon\www\sandbox-mcart\test01.php(9): DatabaseAccessObject->__construct('localhost', 'root', 'password', 'game') #2 {main} thrown in D:\laragon\www\sandbox-mcart\DatabaseAccessObject.php on line 22
mysqli_connect_errno() 根本不會執行!!!?
如果是API方式,存取!!那錯誤訊息,不會顯示出來喔!!!因為停在mysqli_connect...